package algorithms.sedgewick.part1.sort;



/*************************************************************************
 * Name:
 * Email:
 *
 * Compilation:  javac Point.java
 * Execution:
 * Dependencies: StdDraw.java
 *
 * Description: An immutable data type for points in the plane.
 *
 *************************************************************************/

import java.util.Comparator;

public class Point implements Comparable<Point> {

	// compare points by slope
	public final Comparator<Point> SLOPE_ORDER = new SlopeComparator();       // YOUR DEFINITION HERE

	private final int x;                              // x coordinate
	private final int y;                              // y coordinate

	// create the point (x, y)
	public Point(int x, int y) {
		/* DO NOT MODIFY */
		this.x = x;
		this.y = y;
	}

	// plot this point to standard drawing
	public void draw() {
		// DO NOT MODIFY 
		StdDraw.point(x, y);
	}

	// draw line between this point and that point to standard drawing
	public void drawTo(Point that) {
		// DO NOT MODIFY 
		StdDraw.line(this.x, this.y, that.x, that.y);
	}

	// slope between this point and that point
	public double slopeTo(Point that) {
		/* YOUR CODE HERE */
		//samurai
		if(that==null){
			throw new NullPointerException();
		}
		double slope = 0;
		if(this.x == that.x){
			if(this.y==that.y){
				slope = Double.NEGATIVE_INFINITY;
			}
			else{
				slope = Double.POSITIVE_INFINITY;
			}
		}
		else if(this.y != that.y){
			slope = (that.y - this.y)*1.0/(that.x - this.x);
		}
		return slope;
	}

	// is this point lexicographically smaller than that one?
	// comparing y-coordinates and breaking ties by x-coordinates
	public int compareTo(Point that) {
		if(that==null){
			throw new NullPointerException();
		}
		/* YOUR CODE HERE */
		//samurai
		int compareResult=1;

		if((this.y < that.y) ||
				(this.y == that.y &&
				this.x < that.x)){
			compareResult = -1;
		}
		else if((this.x == that.x) &&
				(this.y == that.y)){
			compareResult = 0;
		}
		return compareResult;
	}

	// return string representation of this point
	public String toString() {
		/* DO NOT MODIFY */
		return "(" + x + ", " + y + ")";
	}

	// unit test
	public static void main(String[] args) {
		/* YOUR CODE HERE */
		Point p = new Point(3,1);
		Point q = new Point(2,6);
		Point r = new Point(3,1);
		System.out.println(p.slopeTo(q));
		System.out.println(p.slopeTo(r));
		System.out.println(p.SLOPE_ORDER.compare(q, r));
	}

	private class SlopeComparator implements Comparator<Point>{

		public int compare(Point o1, Point o2) {
			return Double.compare(slopeTo(o1), slopeTo(o2));
		}

	}
}
